package org.example.demo2.service.impl;

import com.fasterxml.jackson.databind.ObjectMapper;
import org.example.demo2.config.RabbitmqConfig;
import org.example.demo2.entity.Like;
import org.example.demo2.entity.LikeDTO;
import org.example.demo2.mapper.LikeMapper;
import org.example.demo2.mq.RabbitManager;
import org.example.demo2.service.ConfirmCallbackService;
import org.example.demo2.service.LikeService;
import org.springframework.amqp.core.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.Duration;
import java.util.List;

/**
 * @ClassName Producer
 * @Description 生产者
 * @Author Kx
 * @Date 2025/10/13 8:42
 * @Version 1.0
 */
@Service
public class LikeServiceImpl implements LikeService, ConfirmCallbackService {
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @Autowired
    private LikeMapper likeMapper;
    @Autowired
    private RabbitManager<LikeDTO> rabbitManager;

    // 存储用户点赞
    private static final String USER_LIKE_SET_PREFIX = "post:like:";

    /**
     * @author: kx
     * @date: 2025/10/13 19:44
     * @param postId : 帖子ID
     * @param userId : 用户ID
     * @description: 点赞
    */
    @Override
    public void like(Integer postId, Integer userId) {
        boolean likeStatus = false;
        if (isLike(postId, userId)) {
            // 把该用户的ID从集合中移除
            redisTemplate.opsForSet().remove(USER_LIKE_SET_PREFIX + postId, userId);
        } else {
            // 设置为已点赞
            likeStatus = true;
            // 添加用户点赞帖子信息
            redisTemplate.opsForSet().add(USER_LIKE_SET_PREFIX + postId, userId);
        }

        // 获取帖子点赞数
        Long likeCount = redisTemplate.opsForSet().size(USER_LIKE_SET_PREFIX + postId);

        LikeDTO likeDTO = new LikeDTO(likeStatus, postId, userId, likeCount);
        // 消息投递
        rabbitManager.send(RabbitmqConfig.EXCHANGE_NAME, RabbitmqConfig.ROUTING_KEY, "likeService", likeDTO);
    }

    @Override
    public Boolean isLike(Integer postId, Integer userId) {
        // 判断缓存中是否有用户点赞帖子信息
        if (Boolean.FALSE.equals(redisTemplate.hasKey(USER_LIKE_SET_PREFIX + postId))) {
            List<Like> listLike = likeMapper.getListLikeByPostId(postId);
            for (Like like : listLike) {
                // 添加用户点赞帖子信息
                redisTemplate.opsForSet().add(USER_LIKE_SET_PREFIX + postId, like.getUserId());
                // 设置过期时间
                redisTemplate.expire(USER_LIKE_SET_PREFIX + postId, Duration.ofHours(72));
            }
        }
        // 判断用户是否点赞
        return redisTemplate.opsForSet().isMember(USER_LIKE_SET_PREFIX + postId, userId);
    }

    /**
     * @author: kx
     * @date: 2025/10/15 15:05
     * @param message : 消息
     * @description: 失败后的回调处理器
    */
    @Override
    public void confirm(Message message) {
        // 获取消息体
        byte[] bytes = message.getBody();
        try {
            // 反序列化消息体成为 LikeDTO 对象
            LikeDTO likeDTO = new ObjectMapper().readValue(bytes, LikeDTO.class);
            if (likeDTO.getLike()) {
                // 移除用户点赞帖子信息
                redisTemplate.opsForSet().remove(USER_LIKE_SET_PREFIX + likeDTO.getPostId(), likeDTO.getUserId());
            } else {
                // 添加用户点赞帖子信息
                redisTemplate.opsForSet().add(USER_LIKE_SET_PREFIX + likeDTO.getPostId(), likeDTO.getUserId());
            }
        }catch (Exception e){
            throw new RuntimeException("消息发送失败");
        }
    }
}
